COMMENTS = {'--', '//'}
OPERATORS = [{'**'}, {'+', '-', '*', '/', ';', ',', '(', ')'}]
ALLOWED = {'_'}


def tokenize(src):
    src = src.lower()
    tokens = []
    i = 0
    while i < len(src):
        # skip white space
        if src[i] in {' ', '\n'}:
            i += 1
            continue
        # skip comment
        if src[i:i+2] in COMMENTS:
            while i < len(src):
                if src[i] == '\n':
                    break
                i += 1
            i += 1
            continue
        # recognize operator
        if src[i:i+2] in OPERATORS[0]:
            tokens.append(src[i:i+2])
            i += 2
            continue
        elif src[i:i+1] in OPERATORS[1]:
            tokens.append(src[i:i+1])
            i += 1
            continue
        # recognize digit
        offset = get_digit_len(src[i:])
        if offset > 0:
            tokens.append(src[i:i+offset])
            i += offset
            continue
        # recognize identifier
        offset = get_idetifier_len(src[i:])
        if offset > 0:
            tokens.append(src[i:i+offset])
            # set i point to the last char of identifier
            i += offset
            continue
        raise RuntimeError('ERROR_WRONG_TOKEN')
    return tokens


def get_idetifier_len(src):
    i = 0
    if not (src[0].isalpha() or src[0] == '_'):
        return 0
    while i < len(src):
        if not (src[i].isalpha() or is_num(src[i], signed=False) or src[i] in ALLOWED):
            return i
        i += 1
    return i


def get_digit_len(src):
    i = 0
    while i < len(src):
        if not is_num(src[i], signed=False):
            return i
        i += 1
    return i


def is_num(src, signed=False):
    dot = False
    i = 0
    while i < len(src):
        char = src[i]
        # filter illegal char
        if not signed:
            if not (char.isdigit() or char in {'.'}):
                return False
        else:
            if not (char.isdigit() or char in {'.', '-', '+'}):
                return False
            if char in {'-', '+'} and i != 0:
                return False
            if char in {'-', '+'} and len(src) == 1:
                return False
        # handle '.'
        if char == '.':
            if dot:
                return False
            else:
                dot = True
        i += 1
    return True

if __name__ == '__main__':
    # src = '--asd\n+***-/main+l'
    # tokens = tokenize(src)
    # print (tokens)
    print (is_num('1'))
